package com.fast.develop.core.io.db;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.fast.develop.core.io.Folder;
import com.fast.develop.core.io.ResourceManager;
import com.fast.develop.core.io.memory.MemoryFileSystem;
import com.fast.develop.core.io.memory.MemoryFolder;
import lombok.extern.slf4j.Slf4j;

import java.util.Collection;
import java.util.List;

/**
 * @author 莫寅
 * @createTime 2022-06-23 01:44
 * @desc：
 */
@Slf4j
public class DbResourceManager implements ResourceManager {

    private MemoryFileSystem memoryFileSystem = null;
    private DbResourceRepository dbResourceRepository;


    public DbResourceManager(DbResourceRepository dbResourceRepository) {
        this.dbResourceRepository = dbResourceRepository;

        reload();
    }

    /**
     * 重新加载
     */
    @Override
    public void reload(){
        this.memoryFileSystem = new MemoryFileSystem();
        List<DbResource> dbResourceEntities = dbResourceRepository.list();
        dbResourceEntities.stream().forEach(dbResourceEntity -> {
            if(dbResourceEntity.getContent() != null){
                if(FileUtil.getSuffix(dbResourceEntity.getPath()).equals("json")){
                    memoryFileSystem.write(dbResourceEntity.getPath(), dbResourceEntity.getContent().getBytes());
                }
            }

        });


        memoryFileSystem.mark();
    }

    @Override
    public void createFolder(String path) {
        MemoryFolder memoryFolder = new MemoryFolder(memoryFileSystem, path);
        memoryFileSystem.createFolder(memoryFolder);
        String markFile = getPath(path, ".mark");
        createFile(markFile);
        flush();
    }

    @Override
    public void createFile(String name) {
        write(name, new byte[]{});
        flush();
    }

    @Override
    public void createFile(String name, byte[] bytes) {
        write(name, bytes);
        flush();
    }

    @Override
    public String rename(String path, String newName) {
        dbResourceRepository.rename(path, newName);
        reload();

        return "";
    }

    @Override
    public Folder getRootFolder() {
        return memoryFileSystem.getRootFolder();
    }

    @Override
    public boolean isAvailable(String pResourceName) {
        return memoryFileSystem.isAvailable(pResourceName);
    }

    @Override
    public byte[] getBytes(String pResourceName) {
        return memoryFileSystem.getBytes(pResourceName);
    }

    @Override
    public Collection<String> getFileNames() {
        return memoryFileSystem.getFileNames();
    }

    @Override
    public Collection<String> getFolderNames() {
        return memoryFileSystem.getFolderNames();
    }

    @Override
    public Collection<String> getModifiedResourcesSinceLastMark() {
        return null;
    }

    @Override
    public void write(String pResourceName, byte[] pResourceData) {
        memoryFileSystem.write(pResourceName, pResourceData);

    }

    @Override
    public void write(String pResourceName, byte[] pResourceData, boolean createFolder) {
        memoryFileSystem.write(pResourceName, pResourceData, createFolder);

    }

    @Override
    public byte[] read(String pResourceName) {
        return memoryFileSystem.read(pResourceName);
    }

    @Override
    public void remove(String path) {
        //是否是文件夹
        if(memoryFileSystem.existsFolder(path)){
            Folder folder = new MemoryFolder(memoryFileSystem, path);
            memoryFileSystem.remove(folder);
            flush();
        }
        //是否是文件
        else if(memoryFileSystem.existsFile(path)){
            memoryFileSystem.remove(path);
            flush();
        }

    }

    private void flush(){
        memoryFileSystem.getModifiedResourcesSinceLastMark().stream().forEach(s -> flush(s));
        memoryFileSystem.mark();
    }

    private void flush(String path){
        //是否是文件夹
        if(memoryFileSystem.existsFolder(path)){
            dbResourceRepository.createFolder(path);
            if(log.isDebugEnabled()){
                log.debug("将文件夹写入Db：{}", path);
            }
        }
        //是否是文件
        else if(memoryFileSystem.existsFile(path)){
            byte[] bytes = memoryFileSystem.read(path);
            dbResourceRepository.createFile(path, bytes);
            if(log.isDebugEnabled()){
                log.debug("将文件写入DB：{}", path);
            }
        }
        //都不存在则已删除
        else{
            if(log.isDebugEnabled()){
                log.debug("将文件从Db中删除：{}", path);
            }
            dbResourceRepository.deleteByPath(path);
        }

    }


    private String getPath(String path, String name){
        if(path.charAt(path.length()-1) != StrUtil.SLASH.charAt(0)){
            path += "/";
        }

        if(name.indexOf(StrUtil.SLASH) == 0){
            name = name.substring(1, name.length());
        }
        return path + name;
    }

}
